/*!
 * \file UftStrategyMgr.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief UFT策略管理器定义文件
 * 
 * \details 定义了UFT(Ultra Fast Trading)策略管理器类，负责UFT策略工厂的加载、
 *          策略实例的创建和管理。支持动态加载策略工厂DLL，管理策略生命周期，
 *          提供策略查找和访问接口。
 */
#pragma once
#include <memory>
#include <boost/core/noncopyable.hpp>

#include "../Includes/FasterDefs.h"
#include "../Includes/UftStrategyDefs.h"

#include "../Share/DLLHelper.hpp"

/*!
 * \class UftStraWrapper
 * \brief UFT策略包装器类
 * 
 * \details 封装UFT策略实例和策略工厂指针，采用RAII模式管理策略生命周期。
 *          当包装器析构时，自动调用工厂的删除方法释放策略资源，确保内存安全。
 * 
 * \note 该类采用智能指针管理，支持共享所有权
 */
class UftStraWrapper
{
public:
	/*!
	 * \brief 构造函数
	 * \param stra UFT策略实例指针
	 * \param fact UFT策略工厂接口指针
	 * 
	 * \details 初始化包装器，建立策略实例与工厂的关联关系
	 */
	UftStraWrapper(UftStrategy* stra, IUftStrategyFact* fact) :_stra(stra), _fact(fact){}
	
	/*!
	 * \brief 析构函数
	 * 
	 * \details 自动调用策略工厂的deleteStrategy方法释放策略资源，
	 *          实现RAII资源管理模式
	 */
	~UftStraWrapper()
	{
		if (_stra)
		{
			_fact->deleteStrategy(_stra);
		}
	}

	/*!
	 * \brief 获取策略实例指针
	 * \return UftStrategy* 策略实例指针
	 * 
	 * \details 提供对封装的策略实例的访问接口
	 */
	UftStrategy* self(){ return _stra; }


private:
	UftStrategy*		_stra;	///< UFT策略实例指针
	IUftStrategyFact*	_fact;	///< UFT策略工厂接口指针
};

typedef std::shared_ptr<UftStraWrapper>	UftStrategyPtr;	///< UFT策略智能指针类型定义

/*!
 * \class UftStrategyMgr
 * \brief UFT策略管理器类
 * 
 * \details UFT(Ultra Fast Trading)策略管理器，负责管理所有UFT策略工厂和策略实例。
 *          主要功能包括：
 *          - 动态加载策略工厂DLL模块
 *          - 创建和管理策略实例
 *          - 提供策略查找和访问接口
 *          - 管理策略生命周期
 * 
 * \note 该类继承自boost::noncopyable，禁止拷贝和赋值操作
 * \warning 所有策略工厂必须在使用前通过loadFactories方法加载
 */
class UftStrategyMgr : private boost::noncopyable
{
public:
	/*!
	 * \brief 构造函数
	 * 
	 * \details 初始化UFT策略管理器，创建空的工厂映射和策略映射
	 */
	UftStrategyMgr();
	
	/*!
	 * \brief 析构函数
	 * 
	 * \details 清理所有已加载的策略工厂和策略实例，释放相关资源
	 */
	~UftStrategyMgr();

public:
	/*!
	 * \brief 加载策略工厂
	 * \param path 策略工厂DLL文件目录路径
	 * \return bool 加载成功返回true，失败返回false
	 * 
	 * \details 扫描指定目录下的所有DLL文件，尝试加载UFT策略工厂。
	 *          对每个DLL文件：
	 *          1. 加载动态库
	 *          2. 获取工厂创建和删除函数
	 *          3. 创建工厂实例
	 *          4. 注册到工厂映射表
	 * 
	 * \note 该方法通常在系统启动时调用一次
	 * \warning 确保路径下的DLL文件是有效的UFT策略工厂
	 */
	bool loadFactories(const char* path);

	/*!
	 * \brief 根据策略名称创建策略实例
	 * \param name 策略名称
	 * \param id 策略实例ID
	 * \return UftStrategyPtr 策略智能指针，创建失败返回nullptr
	 * 
	 * \details 通过策略名称在已加载的工厂中查找匹配的工厂，
	 *          使用该工厂创建策略实例
	 * 
	 * \note 策略ID必须唯一，不能重复
	 */
	UftStrategyPtr createStrategy(const char* name, const char* id);
	
	/*!
	 * \brief 根据工厂名称和策略名称创建策略实例
	 * \param factname 工厂名称
	 * \param unitname 策略单元名称
	 * \param id 策略实例ID
	 * \return UftStrategyPtr 策略智能指针，创建失败返回nullptr
	 * 
	 * \details 先根据工厂名称查找工厂，再根据策略单元名称创建策略实例。
	 *          这种方式提供更精确的策略创建控制
	 * 
	 * \note 策略ID必须唯一，不能重复
	 */
	UftStrategyPtr createStrategy(const char* factname, const char* unitname, const char* id);

	/*!
	 * \brief 根据ID获取策略实例
	 * \param id 策略实例ID
	 * \return UftStrategyPtr 策略智能指针，未找到返回nullptr
	 * 
	 * \details 在策略映射表中查找指定ID的策略实例
	 */
	UftStrategyPtr getStrategy(const char* id);

private:
	/*!
	 * \struct _StraFactInfo
	 * \brief 策略工厂信息结构体
	 * 
	 * \details 存储每个已加载策略工厂的详细信息，包括：
	 *          - DLL模块路径和句柄
	 *          - 工厂实例指针
	 *          - 工厂创建和删除函数指针
	 * 
	 * \note 析构时自动调用删除函数释放工厂资源
	 */
	typedef struct _StraFactInfo
	{
		std::string		_module_path;	///< DLL模块文件路径
		DllHandle		_module_inst;	///< DLL模块句柄
		IUftStrategyFact*	_fact;		///< 策略工厂实例指针
		FuncCreateUftStraFact	_creator;	///< 工厂创建函数指针
		FuncDeleteUftStraFact	_remover;	///< 工厂删除函数指针

		/*!
		 * \brief 构造函数
		 * 
		 * \details 初始化所有指针为NULL
		 */
		_StraFactInfo()
		{
			_module_inst = NULL;
			_fact = NULL;
		}

		/*!
		 * \brief 析构函数
		 * 
		 * \details 如果工厂实例存在，调用删除函数释放资源
		 */
		~_StraFactInfo()
		{
			if (_fact)
				_remover(_fact);
		}
	} StraFactInfo;
	typedef faster_hashmap<std::string, StraFactInfo> StraFactMap;	///< 策略工厂映射表类型

	StraFactMap	_factories;		///< 策略工厂映射表，键为工厂名称

	typedef faster_hashmap<std::string, UftStrategyPtr> StrategyMap;	///< 策略映射表类型
	StrategyMap	_strategies;	///< 策略实例映射表，键为策略ID
};

